import { computed, shallowRef } from 'vue';
import { createInjectionState } from '@vueuse/core';
import { TableColumnType } from 'ant-design-vue';

interface defaultValue {
  remoteColumns?: () => Promise<TableColumnType[]>;
  setRemoteColumns?: (columns: TableColumnType[]) => void;
}

const [useProvideColumnsStore, useColumnsStore] = createInjectionState(
  (initialValue: defaultValue) => {
    const sourceColumn = shallowRef<TableColumnType[]>([]);

    const _columns = shallowRef<TableColumnType[]>([]);

    if (initialValue.remoteColumns) {
      initialValue.remoteColumns().then((res) => {
        if (res?.length) {
          _columns.value = res;
        } else {
          reset();
        }
      });
    }

    const setRemoteColumns = () => {
      initialValue.setRemoteColumns?.(
        _columns.value.map((item) => {
          const { dataIndex, checked = true, fixed = false, title } = item;
          return {
            dataIndex,
            checked,
            fixed,
            title,
          };
        }),
      );
    };

    //  对单列数据更新
    const updateColumn = (key: string, value: TableColumnType) => {
      _columns.value = _columns.value.map((item) => {
        if (item.dataIndex === key) {
          item = {
            ...item,
            ...value,
          };
        }
        return item;
      });
      setRemoteColumns();
    };

    // 对整个 table 列更新
    const updateColumns = (columns: TableColumnType[]) => {
      _columns.value = columns;
      setRemoteColumns();
    };

    const updateSourceColumns = (columns: TableColumnType[]) => {
      sourceColumn.value = columns;
    };

    const reset = () => {
      _columns.value = sourceColumn.value;
      setRemoteColumns();
    };

    const _columnsMap = computed(() => {
      return new Map<string, TableColumnType & { __order__: number }>(
        _columns.value.map((col, index) => {
          const { checked, fixed } = col;
          return [
            col.dataIndex as string,
            {
              checked,
              fixed,
              __order__: index,
            },
          ];
        }),
      );
    });

    const currentColumns = computed(() => {
      return sourceColumn.value
        .map((item) => {
          return {
            ...item,
            ..._columnsMap.value.get(item.dataIndex as string),
          };
        })
        .sort((prev, cur) => prev.__order__! - cur.__order__!);
    });

    return {
      currentColumns,
      sourceColumn,
      updateColumn,
      updateColumns,
      reset,
      updateSourceColumns,
    };
  },
);

export { useProvideColumnsStore, useColumnsStore };
